streamlit-nightly 1.43.3.dev20250317__py3-none-any.whl → 1.43.3.dev20250319__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/auth_util.py +1 -1
- streamlit/commands/page_config.py +1 -1
- streamlit/config.py +141 -45
- streamlit/config_option.py +4 -1
- streamlit/config_util.py +1 -1
- streamlit/connections/snowflake_connection.py +2 -2
- streamlit/connections/snowpark_connection.py +1 -1
- streamlit/connections/sql_connection.py +1 -1
- streamlit/connections/util.py +1 -1
- streamlit/dataframe_util.py +12 -12
- streamlit/delta_generator.py +2 -2
- streamlit/deprecation_util.py +2 -2
- streamlit/elements/arrow.py +3 -3
- streamlit/elements/deck_gl_json_chart.py +4 -4
- streamlit/elements/dialog_decorator.py +2 -2
- streamlit/elements/heading.py +1 -1
- streamlit/elements/html.py +3 -3
- streamlit/elements/lib/built_in_chart_utils.py +9 -8
- streamlit/elements/lib/color_util.py +7 -7
- streamlit/elements/lib/dialog.py +1 -1
- streamlit/elements/lib/image_utils.py +9 -7
- streamlit/elements/lib/mutable_status_container.py +1 -1
- streamlit/elements/media.py +2 -2
- streamlit/elements/metric.py +1 -1
- streamlit/elements/plotly_chart.py +4 -4
- streamlit/elements/vega_charts.py +5 -5
- streamlit/elements/widgets/button_group.py +1 -1
- streamlit/elements/widgets/multiselect.py +3 -2
- streamlit/elements/widgets/select_slider.py +3 -5
- streamlit/elements/widgets/slider.py +4 -4
- streamlit/elements/widgets/time_widgets.py +4 -4
- streamlit/elements/write.py +1 -1
- streamlit/material_icon_names.py +1 -1
- streamlit/proto/NewSession_pb2.py +16 -16
- streamlit/proto/NewSession_pb2.pyi +22 -11
- streamlit/runtime/app_session.py +10 -7
- streamlit/runtime/caching/cache_data_api.py +2 -2
- streamlit/runtime/caching/cache_resource_api.py +2 -2
- streamlit/runtime/caching/hashing.py +7 -7
- streamlit/runtime/metrics_util.py +1 -1
- streamlit/runtime/scriptrunner/script_runner.py +2 -2
- streamlit/runtime/scriptrunner_utils/script_requests.py +1 -1
- streamlit/runtime/session_manager.py +1 -1
- streamlit/runtime/state/session_state.py +3 -3
- streamlit/runtime/websocket_session_manager.py +2 -2
- streamlit/static/index.html +2 -2
- streamlit/static/static/css/{index.DQZt7VFg.css → index.BOl9eq08.css} +1 -1
- streamlit/static/static/css/index.C5t3M85E.css +1 -0
- streamlit/static/static/js/{FileDownload.esm.DPWNg8L0.js → FileDownload.esm.Dz4lqu2t.js} +1 -1
- streamlit/static/static/js/{FileHelper.Be9l1B23.js → FileHelper.B_o0E5mY.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.Ck_v4Tgg.js → FormClearHelper.B5ARMjis.js} +1 -1
- streamlit/static/static/js/{Hooks.B0Mdn8OE.js → Hooks.gYcZ3nte.js} +1 -1
- streamlit/static/static/js/{InputInstructions.DEfhAJgc.js → InputInstructions.K_vAW_MG.js} +1 -1
- streamlit/static/static/js/{ProgressBar.D34ZfmP5.js → ProgressBar.DOjGuUdH.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.D7rG7dkm.js → RenderInPortalIfExists.C4HdMGrO.js} +1 -1
- streamlit/static/static/js/{Toolbar.BKx7cxA3.js → Toolbar.BZqFuVCo.js} +1 -1
- streamlit/static/static/js/{base-input.D400PpZv.js → base-input.DtNLPEYc.js} +1 -1
- streamlit/static/static/js/{checkbox.T2_9UyBa.js → checkbox.De5lDKlG.js} +1 -1
- streamlit/static/static/js/{createSuper.B6r1ToQR.js → createSuper.DUfdjejQ.js} +1 -1
- streamlit/static/static/js/data-grid-overlay-editor.ByFOuSZw.js +1 -0
- streamlit/static/static/js/{downloader.CfgCJjqI.js → downloader.Bndt7ayy.js} +1 -1
- streamlit/static/static/js/{es6.BIR4_s9Q.js → es6.B9axslaM.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.BvHB3v_q.js → iframeResizer.contentWindow.C19fTVqS.js} +1 -1
- streamlit/static/static/js/{index.P1KdGEyu.js → index.3vPW8lC3.js} +1 -1
- streamlit/static/static/js/{index.-19Q4tZa.js → index.8fEQ0naY.js} +1 -1
- streamlit/static/static/js/{index.ChU_mie6.js → index.B9N7bKyh.js} +1 -1
- streamlit/static/static/js/{index.4XxlReRC.js → index.BBkaxxeO.js} +1 -1
- streamlit/static/static/js/index.BDWxQ6IH.js +3 -0
- streamlit/static/static/js/{index.CY8FtTk0.js → index.BELm1MW6.js} +1 -1
- streamlit/static/static/js/{index.B6BwNYBs.js → index.BKE695Zg.js} +1 -1
- streamlit/static/static/js/{index.BlTWh14x.js → index.BKhwcUMH.js} +83 -83
- streamlit/static/static/js/index.BOsCHoek.js +1 -0
- streamlit/static/static/js/{index.CPHXX3ut.js → index.BQkmoKYZ.js} +1 -1
- streamlit/static/static/js/{index.1Y_wlVII.js → index.BRjv0YAi.js} +1 -1
- streamlit/static/static/js/index.BTbDncVq.js +1 -0
- streamlit/static/static/js/{index.wuPpurow.js → index.BVKRKiWg.js} +1 -1
- streamlit/static/static/js/{index.B8cYOVy0.js → index.Bbd47eDn.js} +1 -1
- streamlit/static/static/js/index.Bk2R3MJ7.js +1 -0
- streamlit/static/static/js/{index.BsoT67Bp.js → index.BoIgF6Mf.js} +2 -2
- streamlit/static/static/js/{index.CxgOTC1d.js → index.BpkIFU8i.js} +1 -1
- streamlit/static/static/js/{index.BvRYYdLA.js → index.BrZWnIcP.js} +1 -1
- streamlit/static/static/js/index.Bu7fiR4T.js +1 -0
- streamlit/static/static/js/{index.mDzBI6l2.js → index.C4zUVQy-.js} +1 -1
- streamlit/static/static/js/index.CBtAFng_.js +1 -0
- streamlit/static/static/js/{index.D3XyyrNG.js → index.CGzFdF4L.js} +2 -2
- streamlit/static/static/js/{index.B1y58sqw.js → index.CKmyhCjm.js} +1 -1
- streamlit/static/static/js/index.CVbLNEv4.js +1 -0
- streamlit/static/static/js/{index.CW3wpu7l.js → index.CYG25qUi.js} +1 -1
- streamlit/static/static/js/{index.M8jMYQHQ.js → index.DCgNoHge.js} +3 -3
- streamlit/static/static/js/{index.Bw2C-uyr.js → index.DJzV_Hd9.js} +1 -1
- streamlit/static/static/js/{index.DdaG6BEp.js → index.DQ8O6p2Z.js} +1 -1
- streamlit/static/static/js/{index.D7KT3HOJ.js → index.DWQ-qPH7.js} +1 -1
- streamlit/static/static/js/{index.BZJaY1ZU.js → index.DxsZ6SOh.js} +1 -1
- streamlit/static/static/js/index.K2n8XAB3.js +2 -0
- streamlit/static/static/js/{index.D7j_uG-4.js → index.KmpTf7BC.js} +16 -16
- streamlit/static/static/js/{index.2z1MQMgc.js → index.TIHw6394.js} +1 -1
- streamlit/static/static/js/{index.BebPGQSk.js → index.TXEfAqTZ.js} +1 -1
- streamlit/static/static/js/index.bco4avsR.js +1 -0
- streamlit/static/static/js/{index.C01swFeE.js → index.cHVEPjHw.js} +2 -2
- streamlit/static/static/js/index.xvt4PCc-.js +1 -0
- streamlit/static/static/js/{input.BjUJQgVM.js → input.5dHsg5IP.js} +1 -1
- streamlit/static/static/js/{memory.7TMii04U.js → memory.7AvKwFql.js} +1 -1
- streamlit/static/static/js/{mergeWith.BXLP9sI5.js → mergeWith.Bz2fCjZ-.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.C2Z8Sd28.js → number-overlay-editor.BzFQCoPo.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.3LXCoGeT.js → possibleConstructorReturn.BWYpSIhJ.js} +1 -1
- streamlit/static/static/js/{sandbox.BRs-5jl_.js → sandbox.DDDzfccc.js} +1 -1
- streamlit/static/static/js/{textarea.DT8T2CKm.js → textarea.UlZOYsGE.js} +1 -1
- streamlit/static/static/js/{timepicker.BQDylQL_.js → timepicker.C8uTDs22.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.C9LiuPCd.js → toConsumableArray.CdG0Nv6r.js} +1 -1
- streamlit/static/static/js/{uniqueId.CVZfBH3U.js → uniqueId.hWzaDSRc.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.DgSV341D.js → useBasicWidgetState.CtYBARrn.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.D1W4Nc13.js → useOnInputChange.Cpz9bdhf.js} +1 -1
- streamlit/static/static/js/withFullScreenWrapper.BcDfXDtz.js +1 -0
- streamlit/static/static/media/MaterialSymbols-Rounded.BFCIvovZ.woff2 +0 -0
- streamlit/string_util.py +1 -1
- streamlit/testing/v1/element_tree.py +14 -14
- streamlit/watcher/event_based_path_watcher.py +1 -1
- streamlit/web/server/routes.py +1 -0
- {streamlit_nightly-1.43.3.dev20250317.dist-info → streamlit_nightly-1.43.3.dev20250319.dist-info}/METADATA +2 -2
- {streamlit_nightly-1.43.3.dev20250317.dist-info → streamlit_nightly-1.43.3.dev20250319.dist-info}/RECORD +124 -124
- {streamlit_nightly-1.43.3.dev20250317.dist-info → streamlit_nightly-1.43.3.dev20250319.dist-info}/WHEEL +1 -1
- streamlit/static/static/css/index.Bmkmz40k.css +0 -1
- streamlit/static/static/js/data-grid-overlay-editor.CGbd5q6g.js +0 -1
- streamlit/static/static/js/index.B5Gc6Qwv.js +0 -1
- streamlit/static/static/js/index.BD1Jat0A.js +0 -1
- streamlit/static/static/js/index.By9mG2hj.js +0 -1
- streamlit/static/static/js/index.C5wG0y4e.js +0 -3
- streamlit/static/static/js/index.CWQVC9i9.js +0 -1
- streamlit/static/static/js/index.CzCK3xQd.js +0 -1
- streamlit/static/static/js/index.DHk_4dX7.js +0 -2
- streamlit/static/static/js/index.DgjRgqmt.js +0 -1
- streamlit/static/static/js/index.Dl7G-PpD.js +0 -1
- streamlit/static/static/js/index.YQ7W-YC2.js +0 -1
- streamlit/static/static/js/withFullScreenWrapper.DIGqD0pT.js +0 -1
- streamlit/static/static/media/MaterialSymbols-Rounded.CRt5Q-14.woff2 +0 -0
- {streamlit_nightly-1.43.3.dev20250317.data → streamlit_nightly-1.43.3.dev20250319.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.43.3.dev20250317.dist-info → streamlit_nightly-1.43.3.dev20250319.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.43.3.dev20250317.dist-info → streamlit_nightly-1.43.3.dev20250319.dist-info}/top_level.txt +0 -0
streamlit/auth_util.py
CHANGED
@@ -79,7 +79,7 @@ def get_secrets_auth_section() -> AttrDict:
|
|
79
79
|
auth_section = AttrDict({})
|
80
80
|
"""Get the 'auth' section of the secrets.toml."""
|
81
81
|
if secrets_singleton.load_if_toml_exists():
|
82
|
-
auth_section = cast(AttrDict, secrets_singleton.get("auth"))
|
82
|
+
auth_section = cast("AttrDict", secrets_singleton.get("auth"))
|
83
83
|
|
84
84
|
return auth_section
|
85
85
|
|
@@ -262,7 +262,7 @@ def set_page_config(
|
|
262
262
|
msg.page_config_changed.initial_sidebar_state = pb_sidebar_state
|
263
263
|
|
264
264
|
if menu_items is not None:
|
265
|
-
lowercase_menu_items = cast(MenuItems, _lower_clean_dict_keys(menu_items))
|
265
|
+
lowercase_menu_items = cast("MenuItems", _lower_clean_dict_keys(menu_items))
|
266
266
|
validate_menu_items(lowercase_menu_items)
|
267
267
|
menu_items_proto = msg.page_config_changed.menu_items
|
268
268
|
set_menu_items_proto(lowercase_menu_items, menu_items_proto)
|
streamlit/config.py
CHANGED
@@ -22,7 +22,7 @@ import secrets
|
|
22
22
|
import threading
|
23
23
|
from collections import OrderedDict
|
24
24
|
from enum import Enum
|
25
|
-
from typing import Any, Callable
|
25
|
+
from typing import Any, Callable, Literal
|
26
26
|
|
27
27
|
from blinker import Signal
|
28
28
|
|
@@ -86,6 +86,12 @@ class ShowErrorDetailsConfigOptions(str, Enum):
|
|
86
86
|
# command-line and bool when set via user script (e.g. st.set_option("client.showErrorDetails", False)).
|
87
87
|
|
88
88
|
|
89
|
+
class CustomThemeCategories(str, Enum):
|
90
|
+
"""Theme categories that can be set with custom theme config."""
|
91
|
+
|
92
|
+
SIDEBAR = "sidebar"
|
93
|
+
|
94
|
+
|
89
95
|
def set_option(key: str, value: Any, where_defined: str = _USER_DEFINED) -> None:
|
90
96
|
"""Set config option.
|
91
97
|
|
@@ -293,6 +299,36 @@ def _create_option(
|
|
293
299
|
return option
|
294
300
|
|
295
301
|
|
302
|
+
def _create_theme_options(
|
303
|
+
name: str,
|
304
|
+
categories: list[Literal["theme"] | CustomThemeCategories],
|
305
|
+
description: str | None = None,
|
306
|
+
default_val: Any | None = None,
|
307
|
+
visibility: str = "visible",
|
308
|
+
type_: type = str,
|
309
|
+
) -> None:
|
310
|
+
"""
|
311
|
+
Create ConfigOption(s) for a theme-related config option and store it globally in this module.
|
312
|
+
The same config option can be supported for multiple categories, e.g. "theme" and "theme.sidebar".
|
313
|
+
"""
|
314
|
+
for cat in categories:
|
315
|
+
section = cat if cat == "theme" else f"theme.{cat.value}"
|
316
|
+
|
317
|
+
_create_option(
|
318
|
+
f"{section}.{name}",
|
319
|
+
description=description,
|
320
|
+
default_val=default_val,
|
321
|
+
visibility=visibility,
|
322
|
+
type_=type_,
|
323
|
+
scriptable=False,
|
324
|
+
deprecated=False,
|
325
|
+
deprecation_text=None,
|
326
|
+
expiration_date=None,
|
327
|
+
replaced_by=None,
|
328
|
+
sensitive=False,
|
329
|
+
)
|
330
|
+
|
331
|
+
|
296
332
|
def _delete_option(key: str) -> None:
|
297
333
|
"""Remove a ConfigOption by key from the global store.
|
298
334
|
|
@@ -1004,42 +1040,61 @@ _create_option(
|
|
1004
1040
|
|
1005
1041
|
_create_section("theme", "Settings to define a custom theme for your Streamlit app.")
|
1006
1042
|
|
1007
|
-
|
1008
|
-
|
1043
|
+
# Create a section for each custom theme element
|
1044
|
+
for cat in list(CustomThemeCategories):
|
1045
|
+
_create_section(
|
1046
|
+
f"theme.{cat.value}",
|
1047
|
+
f"Settings to define a custom {cat.value} theme in your Streamlit app.",
|
1048
|
+
)
|
1049
|
+
|
1050
|
+
_create_theme_options(
|
1051
|
+
"base",
|
1052
|
+
categories=["theme"],
|
1009
1053
|
description="""
|
1010
1054
|
The preset Streamlit theme that your custom theme inherits from.
|
1011
1055
|
One of "light" or "dark".
|
1012
1056
|
""",
|
1013
1057
|
)
|
1014
1058
|
|
1015
|
-
|
1016
|
-
"
|
1059
|
+
_create_theme_options(
|
1060
|
+
"primaryColor",
|
1061
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1017
1062
|
description="Primary accent color for interactive elements.",
|
1018
1063
|
)
|
1019
1064
|
|
1020
|
-
|
1021
|
-
"
|
1065
|
+
_create_theme_options(
|
1066
|
+
"backgroundColor",
|
1067
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1022
1068
|
description="Background color for the main content area.",
|
1023
1069
|
)
|
1024
1070
|
|
1025
|
-
|
1026
|
-
"
|
1071
|
+
_create_theme_options(
|
1072
|
+
"secondaryBackgroundColor",
|
1073
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1027
1074
|
description="Background color used for the sidebar and most interactive widgets.",
|
1028
1075
|
)
|
1029
1076
|
|
1030
|
-
|
1031
|
-
"
|
1077
|
+
_create_theme_options(
|
1078
|
+
"textColor",
|
1079
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1032
1080
|
description="Color used for almost all text.",
|
1033
1081
|
)
|
1034
1082
|
|
1035
|
-
|
1036
|
-
"
|
1083
|
+
_create_theme_options(
|
1084
|
+
"linkColor",
|
1085
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1037
1086
|
description="Color used for all links.",
|
1038
|
-
visibility="hidden",
|
1039
1087
|
)
|
1040
1088
|
|
1041
|
-
|
1042
|
-
"
|
1089
|
+
_create_theme_options(
|
1090
|
+
"codeBackgroundColor",
|
1091
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1092
|
+
description="Background color used for code blocks.",
|
1093
|
+
)
|
1094
|
+
|
1095
|
+
_create_theme_options(
|
1096
|
+
"font",
|
1097
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1043
1098
|
description="""
|
1044
1099
|
The font family for all text in the app, except code blocks. One of "sans serif",
|
1045
1100
|
"serif", or "monospace".
|
@@ -1047,78 +1102,77 @@ _create_option(
|
|
1047
1102
|
""",
|
1048
1103
|
)
|
1049
1104
|
|
1050
|
-
|
1051
|
-
"
|
1105
|
+
_create_theme_options(
|
1106
|
+
"codeFont",
|
1107
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1052
1108
|
description="""
|
1053
1109
|
The font family to use for code (monospace) in the app.
|
1054
1110
|
To use a custom font, it needs to be added via [theme.fontFaces].
|
1055
1111
|
""",
|
1056
|
-
visibility="hidden",
|
1057
1112
|
)
|
1058
1113
|
|
1059
|
-
|
1060
|
-
"
|
1114
|
+
_create_theme_options(
|
1115
|
+
"headingFont",
|
1116
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1061
1117
|
description="""
|
1062
1118
|
The font family to use for headings in the app.
|
1063
1119
|
To use a custom font, it needs to be added via [theme.fontFaces].
|
1064
1120
|
""",
|
1065
|
-
visibility="hidden",
|
1066
1121
|
)
|
1067
1122
|
|
1068
|
-
|
1069
|
-
"
|
1123
|
+
_create_theme_options(
|
1124
|
+
"fontFaces",
|
1125
|
+
categories=["theme"],
|
1070
1126
|
description="""
|
1071
1127
|
Configure a list of font faces that you can use for the app & code fonts.
|
1072
1128
|
""",
|
1073
|
-
visibility="hidden",
|
1074
1129
|
)
|
1075
1130
|
|
1076
|
-
|
1077
|
-
|
1078
|
-
"theme
|
1131
|
+
_create_theme_options(
|
1132
|
+
"baseRadius",
|
1133
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1079
1134
|
description="""
|
1080
1135
|
The radius used as basis for the corners of most UI elements. Can be:
|
1081
1136
|
"none", "small", "medium", "large", "full", or the number in pixel or rem.
|
1082
1137
|
For example: "10px", "0.5rem", "1.2rem", "2rem".
|
1083
1138
|
""",
|
1084
|
-
visibility="hidden",
|
1085
1139
|
)
|
1086
1140
|
|
1087
|
-
|
1088
|
-
"
|
1141
|
+
_create_theme_options(
|
1142
|
+
"borderColor",
|
1143
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1089
1144
|
description="""
|
1090
1145
|
The color of the border around elements.
|
1091
1146
|
""",
|
1092
|
-
visibility="hidden",
|
1093
1147
|
)
|
1094
1148
|
|
1095
|
-
|
1096
|
-
"
|
1149
|
+
_create_theme_options(
|
1150
|
+
"showWidgetBorder",
|
1151
|
+
categories=["theme", CustomThemeCategories.SIDEBAR],
|
1097
1152
|
description="""
|
1098
|
-
Whether to show a border around input
|
1153
|
+
Whether to show a border around input widgets (e.g. text_input, number_input,
|
1099
1154
|
file_uploader, etc).
|
1100
1155
|
""",
|
1101
1156
|
type_=bool,
|
1102
|
-
visibility="hidden",
|
1103
1157
|
)
|
1104
1158
|
|
1105
|
-
|
1106
|
-
"
|
1159
|
+
_create_theme_options(
|
1160
|
+
"baseFontSize",
|
1161
|
+
categories=["theme"],
|
1107
1162
|
description="""
|
1108
1163
|
Sets the root font size (in pixels) for the app, which determines the overall
|
1109
1164
|
scale of text and UI elements. The default base font size is 16.
|
1110
1165
|
""",
|
1111
1166
|
type_=int,
|
1112
|
-
visibility="hidden",
|
1113
1167
|
)
|
1114
1168
|
|
1115
|
-
|
1116
|
-
"
|
1169
|
+
_create_theme_options(
|
1170
|
+
"showSidebarBorder",
|
1171
|
+
categories=["theme"],
|
1117
1172
|
description="""
|
1118
1173
|
Whether to show a vertical separator between the sidebar and the main content.
|
1119
1174
|
""",
|
1120
1175
|
type_=bool,
|
1121
|
-
visibility="hidden",
|
1122
1176
|
)
|
1123
1177
|
|
1124
1178
|
# Config Section: Secrets #
|
@@ -1275,10 +1329,52 @@ def _update_config_with_toml(raw_toml: str, where_defined: str) -> None:
|
|
1275
1329
|
|
1276
1330
|
parsed_config_file = toml.loads(raw_toml)
|
1277
1331
|
|
1332
|
+
def process_section(section_path: str, section_data: dict[str, Any]) -> None:
|
1333
|
+
"""Recursively process nested sections of the config file.
|
1334
|
+
|
1335
|
+
Parameters
|
1336
|
+
----------
|
1337
|
+
section_path : str
|
1338
|
+
The dot-separated path to the current section (e.g., "server" or "theme")
|
1339
|
+
section_data : dict[str, Any]
|
1340
|
+
The dictionary containing configuration values for this section
|
1341
|
+
|
1342
|
+
Notes
|
1343
|
+
-----
|
1344
|
+
TOML's hierarchical structure gets parsed into nested dictionaries.
|
1345
|
+
For example:
|
1346
|
+
[main]
|
1347
|
+
option = "value"
|
1348
|
+
|
1349
|
+
[main.subsection]
|
1350
|
+
another = "value2"
|
1351
|
+
|
1352
|
+
Will be loaded by the TOML parser as:
|
1353
|
+
{
|
1354
|
+
"main": {
|
1355
|
+
"option": "value",
|
1356
|
+
"subsection": {
|
1357
|
+
"another": "value2"
|
1358
|
+
}
|
1359
|
+
}
|
1360
|
+
}
|
1361
|
+
|
1362
|
+
This function traverses these nested dictionaries and converts them
|
1363
|
+
to dot-notation config options.
|
1364
|
+
"""
|
1365
|
+
|
1366
|
+
for name, value in section_data.items():
|
1367
|
+
option_name = f"{section_path}.{name}"
|
1368
|
+
# Process it as a nested config section if it's a custom theme sub-category
|
1369
|
+
if name in [CustomThemeCategories.SIDEBAR.value]:
|
1370
|
+
process_section(option_name, value)
|
1371
|
+
else:
|
1372
|
+
# It's a regular config option, set it
|
1373
|
+
value = _maybe_read_env_variable(value)
|
1374
|
+
_set_option(option_name, value, where_defined)
|
1375
|
+
|
1278
1376
|
for section, options in parsed_config_file.items():
|
1279
|
-
|
1280
|
-
value = _maybe_read_env_variable(value)
|
1281
|
-
_set_option(f"{section}.{name}", value, where_defined)
|
1377
|
+
process_section(section, options)
|
1282
1378
|
|
1283
1379
|
|
1284
1380
|
def _maybe_read_env_variable(value: Any) -> Any:
|
streamlit/config_option.py
CHANGED
@@ -152,8 +152,11 @@ class ConfigOption:
|
|
152
152
|
# with a lowercase letter with an optional "_" preceding it.
|
153
153
|
# Examples: "_section", "section1"
|
154
154
|
r"\_?[a-z][a-zA-Z0-9]*"
|
155
|
+
# Handling zero or additional parts, separated by period
|
156
|
+
# Examples: "_section.subsection", "section1._section2"
|
157
|
+
r"(\.[a-z][a-zA-Z0-9]*)*"
|
155
158
|
r")"
|
156
|
-
#
|
159
|
+
# The final period, separating section and name
|
157
160
|
r"\."
|
158
161
|
# Capture a group called "name"
|
159
162
|
r"(?P<name>"
|
streamlit/config_util.py
CHANGED
@@ -88,7 +88,7 @@ def show_config(
|
|
88
88
|
out.append("")
|
89
89
|
|
90
90
|
for key, option in section_options.items():
|
91
|
-
key = option.key.split(".")[1]
|
91
|
+
key = option.key.split(".")[-1]
|
92
92
|
description_paragraphs = _clean_paragraphs(option.description or "")
|
93
93
|
|
94
94
|
last_paragraph_idx = len(description_paragraphs) - 1
|
@@ -264,7 +264,7 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
264
264
|
|
265
265
|
return snowflake.connector.connect(**kwargs)
|
266
266
|
except SnowflakeError as e:
|
267
|
-
if not len(st_secrets) and not
|
267
|
+
if not len(st_secrets) and not kwargs:
|
268
268
|
raise StreamlitAPIException(
|
269
269
|
"Missing Snowflake connection configuration. "
|
270
270
|
"Did you forget to set this in `secrets.toml`, a Snowflake configuration file, "
|
@@ -557,5 +557,5 @@ class SnowflakeConnection(BaseConnection["InternalSnowflakeConnection"]):
|
|
557
557
|
return get_active_session()
|
558
558
|
|
559
559
|
return cast(
|
560
|
-
Session, Session.builder.configs({"connection": self._instance}).create()
|
560
|
+
"Session", Session.builder.configs({"connection": self._instance}).create()
|
561
561
|
)
|
@@ -91,7 +91,7 @@ class SnowparkConnection(BaseConnection["Session"]):
|
|
91
91
|
if p not in conn_params:
|
92
92
|
raise StreamlitAPIException(f"Missing Snowpark connection param: {p}")
|
93
93
|
|
94
|
-
return cast(Session, Session.builder.configs(conn_params).create())
|
94
|
+
return cast("Session", Session.builder.configs(conn_params).create())
|
95
95
|
|
96
96
|
def query(
|
97
97
|
self,
|
@@ -390,7 +390,7 @@ class SQLConnection(BaseConnection["Engine"]):
|
|
390
390
|
str
|
391
391
|
The name of the driver. For example, ``"pyodbc"`` or ``"psycopg2"``.
|
392
392
|
"""
|
393
|
-
return cast(str, self._instance.driver)
|
393
|
+
return cast("str", self._instance.driver)
|
394
394
|
|
395
395
|
@property
|
396
396
|
def session(self) -> Session:
|
streamlit/connections/util.py
CHANGED
streamlit/dataframe_util.py
CHANGED
@@ -559,13 +559,13 @@ def convert_anything_to_pandas_df(
|
|
559
559
|
import pandas as pd
|
560
560
|
|
561
561
|
if isinstance(data, pd.DataFrame):
|
562
|
-
return data.copy() if ensure_copy else cast(pd.DataFrame, data)
|
562
|
+
return data.copy() if ensure_copy else cast("pd.DataFrame", data)
|
563
563
|
|
564
564
|
if isinstance(data, (pd.Series, pd.Index, pd.api.extensions.ExtensionArray)):
|
565
565
|
return pd.DataFrame(data)
|
566
566
|
|
567
567
|
if is_pandas_styler(data):
|
568
|
-
return cast(pd.DataFrame, data.data.copy() if ensure_copy else data.data)
|
568
|
+
return cast("pd.DataFrame", data.data.copy() if ensure_copy else data.data)
|
569
569
|
|
570
570
|
if isinstance(data, np.ndarray):
|
571
571
|
return (
|
@@ -589,7 +589,7 @@ def convert_anything_to_pandas_df(
|
|
589
589
|
f"⚠️ Showing only {string_util.simplify_number(max_unevaluated_rows)} "
|
590
590
|
"rows. Call `collect()` on the dataframe to show more."
|
591
591
|
)
|
592
|
-
return cast(pd.DataFrame, data)
|
592
|
+
return cast("pd.DataFrame", data)
|
593
593
|
|
594
594
|
if is_xarray_dataset(data):
|
595
595
|
if ensure_copy:
|
@@ -614,7 +614,7 @@ def convert_anything_to_pandas_df(
|
|
614
614
|
f"⚠️ Showing only {string_util.simplify_number(max_unevaluated_rows)} "
|
615
615
|
"rows. Call `compute()` on the data object to show more."
|
616
616
|
)
|
617
|
-
return cast(pd.DataFrame, data)
|
617
|
+
return cast("pd.DataFrame", data)
|
618
618
|
|
619
619
|
if is_ray_dataset(data):
|
620
620
|
data = data.limit(max_unevaluated_rows).to_pandas()
|
@@ -624,7 +624,7 @@ def convert_anything_to_pandas_df(
|
|
624
624
|
f"⚠️ Showing only {string_util.simplify_number(max_unevaluated_rows)} "
|
625
625
|
"rows. Call `to_pandas()` on the dataset to show more."
|
626
626
|
)
|
627
|
-
return cast(pd.DataFrame, data)
|
627
|
+
return cast("pd.DataFrame", data)
|
628
628
|
|
629
629
|
if is_modin_data_object(data):
|
630
630
|
data = data.head(max_unevaluated_rows)._to_pandas()
|
@@ -637,7 +637,7 @@ def convert_anything_to_pandas_df(
|
|
637
637
|
f"⚠️ Showing only {string_util.simplify_number(max_unevaluated_rows)} "
|
638
638
|
"rows. Call `_to_pandas()` on the data object to show more."
|
639
639
|
)
|
640
|
-
return cast(pd.DataFrame, data)
|
640
|
+
return cast("pd.DataFrame", data)
|
641
641
|
|
642
642
|
if is_pyspark_data_object(data):
|
643
643
|
data = data.limit(max_unevaluated_rows).toPandas()
|
@@ -646,7 +646,7 @@ def convert_anything_to_pandas_df(
|
|
646
646
|
f"⚠️ Showing only {string_util.simplify_number(max_unevaluated_rows)} "
|
647
647
|
"rows. Call `toPandas()` on the data object to show more."
|
648
648
|
)
|
649
|
-
return cast(pd.DataFrame, data)
|
649
|
+
return cast("pd.DataFrame", data)
|
650
650
|
|
651
651
|
if is_snowpandas_data_object(data):
|
652
652
|
data = data[:max_unevaluated_rows].to_pandas()
|
@@ -659,7 +659,7 @@ def convert_anything_to_pandas_df(
|
|
659
659
|
f"⚠️ Showing only {string_util.simplify_number(max_unevaluated_rows)} "
|
660
660
|
"rows. Call `to_pandas()` on the data object to show more."
|
661
661
|
)
|
662
|
-
return cast(pd.DataFrame, data)
|
662
|
+
return cast("pd.DataFrame", data)
|
663
663
|
|
664
664
|
if is_snowpark_data_object(data):
|
665
665
|
data = data.limit(max_unevaluated_rows).to_pandas()
|
@@ -668,7 +668,7 @@ def convert_anything_to_pandas_df(
|
|
668
668
|
f"⚠️ Showing only {string_util.simplify_number(max_unevaluated_rows)} "
|
669
669
|
"rows. Call `to_pandas()` on the data object to show more."
|
670
670
|
)
|
671
|
-
return cast(pd.DataFrame, data)
|
671
|
+
return cast("pd.DataFrame", data)
|
672
672
|
|
673
673
|
if is_duckdb_relation(data):
|
674
674
|
data = data.limit(max_unevaluated_rows).df()
|
@@ -800,7 +800,7 @@ def convert_arrow_table_to_arrow_bytes(table: pa.Table) -> bytes:
|
|
800
800
|
writer = pa.RecordBatchStreamWriter(sink, table.schema)
|
801
801
|
writer.write_table(table)
|
802
802
|
writer.close()
|
803
|
-
return cast(bytes, sink.getvalue().to_pybytes())
|
803
|
+
return cast("bytes", sink.getvalue().to_pybytes())
|
804
804
|
|
805
805
|
|
806
806
|
def convert_pandas_df_to_arrow_bytes(df: DataFrame) -> bytes:
|
@@ -951,7 +951,7 @@ def convert_anything_to_list(obj: OptionSequence[V_co]) -> list[V_co]:
|
|
951
951
|
return (
|
952
952
|
[]
|
953
953
|
if data_df.empty
|
954
|
-
else cast(list[V_co], list(data_df.iloc[:, 0].to_list()))
|
954
|
+
else cast("list[V_co]", list(data_df.iloc[:, 0].to_list()))
|
955
955
|
)
|
956
956
|
except errors.StreamlitAPIException:
|
957
957
|
# Wrap the object into a list
|
@@ -1167,7 +1167,7 @@ def determine_data_format(input_data: Any) -> DataFormat:
|
|
1167
1167
|
elif isinstance(input_data, pd.DataFrame):
|
1168
1168
|
return DataFormat.PANDAS_DATAFRAME
|
1169
1169
|
elif isinstance(input_data, np.ndarray):
|
1170
|
-
if len(cast(NumpyShape, input_data.shape)) == 1:
|
1170
|
+
if len(cast("NumpyShape", input_data.shape)) == 1:
|
1171
1171
|
# For technical reasons, we need to distinguish one
|
1172
1172
|
# one-dimensional numpy array from multidimensional ones.
|
1173
1173
|
return DataFormat.NUMPY_LIST
|
streamlit/delta_generator.py
CHANGED
@@ -538,7 +538,7 @@ class DeltaGenerator(
|
|
538
538
|
dg_type = DeltaGenerator
|
539
539
|
|
540
540
|
block_dg = cast(
|
541
|
-
DeltaGenerator,
|
541
|
+
"DeltaGenerator",
|
542
542
|
dg_type(
|
543
543
|
root_container=dg._root_container,
|
544
544
|
cursor=block_cursor,
|
@@ -566,7 +566,7 @@ class DeltaGenerator(
|
|
566
566
|
|
567
567
|
def _writes_directly_to_sidebar(dg: DeltaGenerator) -> bool:
|
568
568
|
in_sidebar = any(a._root_container == RootContainer.SIDEBAR for a in dg._ancestors)
|
569
|
-
has_container = bool(
|
569
|
+
has_container = bool(list(dg._ancestor_block_types))
|
570
570
|
return in_sidebar and not has_container
|
571
571
|
|
572
572
|
|
streamlit/deprecation_util.py
CHANGED
@@ -105,7 +105,7 @@ def deprecate_func_name(
|
|
105
105
|
# Update the wrapped func's name & docstring so st.help does the right thing
|
106
106
|
wrapped_func.__name__ = old_name
|
107
107
|
wrapped_func.__doc__ = func.__doc__
|
108
|
-
return cast(TFunc, wrapped_func)
|
108
|
+
return cast("TFunc", wrapped_func)
|
109
109
|
|
110
110
|
|
111
111
|
def deprecate_obj_name(
|
@@ -206,4 +206,4 @@ def _create_deprecated_obj_wrapper(obj: TObj, show_warning: Callable[[], Any]) -
|
|
206
206
|
|
207
207
|
return proxy
|
208
208
|
|
209
|
-
return cast(TObj, Wrapper())
|
209
|
+
return cast("TObj", Wrapper())
|
streamlit/elements/arrow.py
CHANGED
@@ -174,7 +174,7 @@ class DataframeSelectionSerde:
|
|
174
174
|
if "selection" not in selection_state:
|
175
175
|
selection_state = empty_selection_state
|
176
176
|
|
177
|
-
return cast(DataframeState, AttributeDictionary(selection_state))
|
177
|
+
return cast("DataframeState", AttributeDictionary(selection_state))
|
178
178
|
|
179
179
|
def serialize(self, editing_state: DataframeState) -> str:
|
180
180
|
return json.dumps(editing_state, default=str)
|
@@ -549,7 +549,7 @@ class ArrowMixin:
|
|
549
549
|
check_widget_policies(
|
550
550
|
self.dg,
|
551
551
|
key,
|
552
|
-
on_change=cast(WidgetCallback, on_select) if is_callback else None,
|
552
|
+
on_change=cast("WidgetCallback", on_select) if is_callback else None,
|
553
553
|
default_value=None,
|
554
554
|
writes_allowed=False,
|
555
555
|
enable_check_callback_rules=is_callback,
|
@@ -644,7 +644,7 @@ class ArrowMixin:
|
|
644
644
|
value_type="string_value",
|
645
645
|
)
|
646
646
|
self.dg._enqueue("arrow_data_frame", proto)
|
647
|
-
return cast(DataframeState, widget_state.value)
|
647
|
+
return cast("DataframeState", widget_state.value)
|
648
648
|
else:
|
649
649
|
return self.dg._enqueue("arrow_data_frame", proto)
|
650
650
|
|
@@ -251,7 +251,7 @@ class PydeckSelectionSerde:
|
|
251
251
|
if "selection" not in selection_state:
|
252
252
|
selection_state = empty_selection_state
|
253
253
|
|
254
|
-
return cast(PydeckState, AttributeDictionary(selection_state))
|
254
|
+
return cast("PydeckState", AttributeDictionary(selection_state))
|
255
255
|
|
256
256
|
def serialize(self, selection_state: PydeckState) -> str:
|
257
257
|
return json.dumps(selection_state, default=str)
|
@@ -488,7 +488,7 @@ class PydeckMixin:
|
|
488
488
|
check_widget_policies(
|
489
489
|
self.dg,
|
490
490
|
key,
|
491
|
-
on_change=cast(WidgetCallback, on_select) if is_callback else None,
|
491
|
+
on_change=cast("WidgetCallback", on_select) if is_callback else None,
|
492
492
|
default_value=None,
|
493
493
|
writes_allowed=False,
|
494
494
|
enable_check_callback_rules=is_callback,
|
@@ -518,7 +518,7 @@ class PydeckMixin:
|
|
518
518
|
|
519
519
|
self.dg._enqueue("deck_gl_json_chart", pydeck_proto)
|
520
520
|
|
521
|
-
return cast(PydeckState, widget_state.value)
|
521
|
+
return cast("PydeckState", widget_state.value)
|
522
522
|
|
523
523
|
return self.dg._enqueue("deck_gl_json_chart", pydeck_proto)
|
524
524
|
|
@@ -541,6 +541,6 @@ def _get_pydeck_tooltip(pydeck_obj: Deck | None) -> dict[str, str] | None:
|
|
541
541
|
# For details, see: https://github.com/visgl/deck.gl/pull/7125/files
|
542
542
|
tooltip = getattr(pydeck_obj, "_tooltip", None)
|
543
543
|
if tooltip is not None and isinstance(tooltip, dict):
|
544
|
-
return cast(dict[str, str], tooltip)
|
544
|
+
return cast("dict[str, str]", tooltip)
|
545
545
|
|
546
546
|
return None
|
@@ -102,7 +102,7 @@ def _dialog_decorator(
|
|
102
102
|
# the fragment decorator has multiple return types so that you can pass
|
103
103
|
# arguments to it. Here we know the return type, so we cast
|
104
104
|
fragmented_dialog_content = cast(
|
105
|
-
Callable[[], None],
|
105
|
+
"Callable[[], None]",
|
106
106
|
_fragment(
|
107
107
|
dialog_content, additional_hash_info=non_optional_func.__qualname__
|
108
108
|
),
|
@@ -112,7 +112,7 @@ def _dialog_decorator(
|
|
112
112
|
fragmented_dialog_content()
|
113
113
|
return None
|
114
114
|
|
115
|
-
return cast(F, wrap)
|
115
|
+
return cast("F", wrap)
|
116
116
|
|
117
117
|
|
118
118
|
@overload
|
streamlit/elements/heading.py
CHANGED
@@ -261,7 +261,7 @@ class HeadingMixin:
|
|
261
261
|
"rainbow",
|
262
262
|
]
|
263
263
|
if divider in valid_colors:
|
264
|
-
return cast(str, divider)
|
264
|
+
return cast("str", divider)
|
265
265
|
else:
|
266
266
|
raise StreamlitAPIException(
|
267
267
|
f"Divider parameter has invalid value: `{divider}`. Please choose from: {', '.join(valid_colors)}."
|
streamlit/elements/html.py
CHANGED
@@ -75,16 +75,16 @@ class HtmlMixin:
|
|
75
75
|
|
76
76
|
# If body supports _repr_html_, use that.
|
77
77
|
if has_callable_attr(body, "_repr_html_"):
|
78
|
-
html_proto.body = cast(SupportsReprHtml, body)._repr_html_()
|
78
|
+
html_proto.body = cast("SupportsReprHtml", body)._repr_html_()
|
79
79
|
|
80
80
|
# Check if the body is a file path. May include filesystem lookup.
|
81
81
|
elif isinstance(body, Path) or _is_file(body):
|
82
|
-
with open(cast(str, body), encoding="utf-8") as f:
|
82
|
+
with open(cast("str", body), encoding="utf-8") as f:
|
83
83
|
html_proto.body = f.read()
|
84
84
|
|
85
85
|
# OK, let's just try converting to string and hope for the best.
|
86
86
|
else:
|
87
|
-
html_proto.body = clean_text(cast(SupportsStr, body))
|
87
|
+
html_proto.body = clean_text(cast("SupportsStr", body))
|
88
88
|
|
89
89
|
return self.dg._enqueue("html", html_proto)
|
90
90
|
|